package com.wawu.common.utils;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class AnnotationUtils {

    /**
     * 通用方法，递归检查类、方法或字段是否包含指定的注解。
     * @param element 被检查的类、方法或字段
     * @param targetAnnotation 目标注解
     * @param recursive 是否递归检查注解上的注解
     * @return 如果存在指定的注解则返回true，否则返回false
     */
    public static boolean isAnnotationPresent(AnnotatedElement element, Class<? extends Annotation> targetAnnotation, boolean recursive) {
        if (element.isAnnotationPresent(targetAnnotation)) {
            return true;
        }
        if (recursive) {
            for (Annotation annotation : element.getAnnotations()) {
                if (isAnnotationPresentOnAnnotation(annotation.annotationType(), targetAnnotation)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 递归检查某个注解本身上是否包含目标注解(会跳过自带注解)
     * @param annotationType 被检查的注解类型
     * @param targetAnnotation 目标注解
     * @return 如果存在目标注解则返回true，否则返回false
     */
    public static boolean isAnnotationPresentOnAnnotation(Class<? extends Annotation> annotationType, Class<? extends Annotation> targetAnnotation) {
        // 跳过标准 Java 注解
        if (annotationType.getName().startsWith("java.lang")) {
            return false;
        }

        for (Annotation annotation : annotationType.getAnnotations()) {
            if (annotation.annotationType().equals(targetAnnotation)) {
                return true;
            }
            // 递归检查注解的注解
            if (isAnnotationPresentOnAnnotation(annotation.annotationType(), targetAnnotation)) {
                return true;
            }
        }
        return false;
    }

    // 简便方法，检查类上是否带有指定注解
    public static boolean isClassAnnotationPresent(Class<?> clazz, Class<? extends Annotation> targetAnnotation, boolean recursive) {
        return isAnnotationPresent(clazz, targetAnnotation, recursive);
    }

    // 简便方法，检查方法上是否带有指定注解
    public static boolean isMethodAnnotationPresent(Method method, Class<? extends Annotation> targetAnnotation, boolean recursive) {
        return isAnnotationPresent(method, targetAnnotation, recursive);
    }

    // 简便方法，检查字段上是否带有指定注解
    public static boolean isFieldAnnotationPresent(Field field, Class<? extends Annotation> targetAnnotation, boolean recursive) {
        return isAnnotationPresent(field, targetAnnotation, recursive);
    }
}
